#include "bsp_fsmc.h"
#include "string.h"
#define SMC_MAX_TIMEOUT                 (0x100000UL)



void Fsmc_Init(void)
{
    LCD_GPIO_Init();
    __IO uint32_t u32To = 0UL;
    int32_t i32Ret = LL_OK;
    stc_exmc_smc_init_t stcSmcInit;
    stc_exmc_smc_chip_config_t stcChipConfig;
    stc_exmc_smc_timing_config_t stcTimingConfig;
    en_flag_status_t enChipStatus = RESET;
    en_flag_status_t enTimingStatus = RESET;
    /* Enable SMC clock */
    FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_SMC, ENABLE);

    /* Enable SMC. */
    EXMC_SMC_Cmd(ENABLE);

    EXMC_SMC_ExitLowPower();

    while (EXMC_SMC_READY != EXMC_SMC_GetStatus()) {
        if (u32To > SMC_MAX_TIMEOUT) {
            i32Ret = LL_ERR;
            break;
        }
        u32To++;
    }

    if (LL_OK == i32Ret) {
        /* Configure SMC width && CS &chip & timing. */
        (void)EXMC_SMC_StructInit(&stcSmcInit);
        stcSmcInit.stcChipConfig.u32AddrMatch = 0x60UL;
        stcSmcInit.stcChipConfig.u32AddrMask  = EXMC_SMC_ADDR_MASK_16MB;
        stcSmcInit.stcChipConfig.u32MemoryWidth  = EXMC_SMC_MEMORY_WIDTH_16BIT;
        stcSmcInit.stcChipConfig.u32BAA  = EXMC_SMC_BAA_PORT_DISABLE;
        stcSmcInit.stcChipConfig.u32ADV  = EXMC_SMC_ADV_PORT_DISABLE;
        stcSmcInit.stcChipConfig.u32BLS  = EXMC_SMC_BLS_SYNC_CS;
        stcSmcInit.stcChipConfig.u32ReadBurstLen  = EXMC_SMC_READ_BURST_4BEAT;
        stcSmcInit.stcChipConfig.u32WriteBurstLen  = EXMC_SMC_WRITE_BURST_4BEAT;
        stcSmcInit.stcChipConfig.u32ReadMode  = EXMC_SMC_READ_SYNC;
        stcSmcInit.stcChipConfig.u32WriteMode  = EXMC_SMC_WRITE_SYNC;
        stcSmcInit.stcTimingConfig.u8RC = 8U;
        stcSmcInit.stcTimingConfig.u8WC = 4U;
        stcSmcInit.stcTimingConfig.u8CEOE = 1U;
        stcSmcInit.stcTimingConfig.u8WP = 2U;
        stcSmcInit.stcTimingConfig.u8PC = 4U;
        stcSmcInit.stcTimingConfig.u8TR = 1U;
        (void)EXMC_SMC_Init(EXMC_SMC_CHIP0, &stcSmcInit);

        /* Set command: updateregs */
        EXMC_SMC_SetCommand(EXMC_SMC_CHIP0, EXMC_SMC_CMD_UPDATEREGS, 0UL, 0UL);

        /* Check timing status */
        u32To = 0UL;
        while ((enChipStatus != SET) || (enTimingStatus != SET)) {
            (void)EXMC_SMC_GetTimingConfig(EXMC_SMC_CHIP0, &stcTimingConfig);
            if (0 == memcmp(&stcTimingConfig, &stcSmcInit.stcTimingConfig, sizeof(stcTimingConfig))) {
                enTimingStatus = SET;
            }

            (void)EXMC_SMC_GetChipConfig(EXMC_SMC_CHIP0, &stcChipConfig);
            if (0 == memcmp(&stcChipConfig, &stcSmcInit.stcChipConfig, sizeof(stcChipConfig))) {
                enChipStatus = SET;
            }

            if (u32To > SMC_MAX_TIMEOUT) {
                i32Ret = LL_ERR;
                break;
            }
            u32To++;
        }
    }

//    return i32Ret;



}

void Fsmc_Dma_Init(void)
{
    LL_PERIPH_WE(LL_PERIPH_FCG);


    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_DMA1 | FCG0_PERIPH_AOS, ENABLE);

    LL_PERIPH_WP(LL_PERIPH_FCG);

    stc_dma_init_t stcDmaInit;

    AOS_SetTriggerEventSrc(AOS_DMA1_3, EVT_SRC_AOS_STRG);

    (void)DMA_StructInit(&stcDmaInit);

    stcDmaInit.u32IntEn      = DMA_INT_ENABLE;
    stcDmaInit.u32BlockSize  = 1024ul;
    stcDmaInit.u32TransCount = 75ul;
    stcDmaInit.u32DataWidth  = DMA_DATAWIDTH_16BIT;
    stcDmaInit.u32DestAddr   = (uint32_t) &*(__IO uint16_t*) FSMC_LCD_DATA;
    stcDmaInit.u32SrcAddr    = 0;
    stcDmaInit.u32SrcAddrInc = DMA_SRC_ADDR_INC;
    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_FIX;
    (void)DMA_Init(CM_DMA1, DMA_CH3, &stcDmaInit);


    stc_irq_signin_config_t stcIrqSignConfig;
    stcIrqSignConfig.enIntSrc   = INT_SRC_DMA1_BTC3;
    stcIrqSignConfig.enIRQn     = INT002_IRQn;
    stcIrqSignConfig.pfnCallback = &DMA1_CH3_BTC_IrqCallback;
    (void)INTC_IrqSignIn(&stcIrqSignConfig);


    DMA_ClearTransCompleteStatus(CM_DMA1, DMA_FLAG_BTC_CH3);

    /* NVIC setting */
    NVIC_ClearPendingIRQ(INT002_IRQn);
    NVIC_SetPriority(INT002_IRQn, DDL_IRQ_PRIO_DEFAULT);
    NVIC_EnableIRQ(INT002_IRQn);


    /* DMA channel enable */
    DMA_Cmd(CM_DMA1, DISABLE);
    (void)DMA_ChCmd(CM_DMA1, DMA_CH3, DISABLE);

}










